package com.java.star.mall.front.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.java.star.mall.common.constant.cache.ProductCacheConstant;
import com.java.star.mall.common.exception.BusinessException;
import com.java.star.mall.common.response.JsonPage;
import com.java.star.mall.common.response.StatusCode;
import com.java.star.mall.front.dao.cache.ProductRepository;
import com.java.star.mall.front.dao.mapper.ProductMapper;
import com.java.star.mall.front.dao.mapper.ProductSwiperImageMapper;
import com.java.star.mall.front.pojo.entity.Product;
import com.java.star.mall.front.pojo.entity.ProductSwiperImage;
import com.java.star.mall.front.pojo.param.SearchParam;
import com.java.star.mall.front.pojo.vo.ProductDetailVO;
import com.java.star.mall.front.pojo.vo.ProductHotVO;
import com.java.star.mall.front.pojo.vo.ProductSwiperVO;
import com.java.star.mall.front.pojo.vo.ProductVO;
import com.java.star.mall.front.properties.ImageProperties;
import com.java.star.mall.front.service.ProductService;
import io.jsonwebtoken.lang.Collections;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * 商品Service实现类
 */
@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private ProductSwiperImageMapper productSwiperImageMapper;

    @Autowired
    private ThreadPoolExecutor executor;

    @Autowired
    private ImageProperties imageProperties;

    @Autowired
    private ProductRepository productRepository;

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 查询轮播商品
     */
    @Override
    public List<ProductSwiperVO> findSwiperProduct() {
        //查询缓存
        List<ProductSwiperVO> productSwiperVOList = productRepository.listSwiperProduct();
        if (!Collections.isEmpty(productSwiperVOList)) {
            //缓存有，直接返回
            return productSwiperVOList;
        }

        //加锁，防止缓存雪崩
        RLock lock = redissonClient.getLock(ProductCacheConstant.SWIPER_PRODUCT_LOCK);
        try {
            lock.lock();
            //再次查看缓存
            productSwiperVOList = productRepository.listSwiperProduct();
            if (!Collections.isEmpty(productSwiperVOList)) {
                //缓存有，直接返回
                return productSwiperVOList;
            }

            //查询数据库轮播商品
            List<Product> productList = productMapper.listSwiperProduct();
            //装配VO内容
            productSwiperVOList = new ArrayList<>();
            if (productList != null && !productList.isEmpty()) {
                productSwiperVOList = productList.stream().map(product -> {
                    ProductSwiperVO productVO = new ProductSwiperVO();
                    BeanUtils.copyProperties(product, productVO);
                    productVO.setSwiperPic(imageProperties.getUrl() + product.getSwiperPic());
                    return productVO;
                }).collect(Collectors.toList());
            }
            //写缓存
            productRepository.addSwiperProduct(productSwiperVOList);

            return productSwiperVOList;
        } finally {
            //放锁
            lock.unlock();
        }
    }

    /**
     * 分页查询热门商品
     */
    @Override
    public JsonPage<ProductHotVO> listHotProduct(Integer page, Integer pageSize) {
        //1.分页查询热门推荐商品
        Page<Object> p = PageHelper.startPage(page, pageSize);
        List<Product> hotProductList = productMapper.listHotProduct();

        //2.装填VO内容
        List<ProductHotVO> hotProductVOList = new ArrayList<>();
        if (!Collections.isEmpty(hotProductList)) {
            hotProductVOList = hotProductList.stream().map(product -> {
                ProductHotVO productVO = new ProductHotVO();
                BeanUtils.copyProperties(product, productVO);
                productVO.setProPic(imageProperties.getUrl() + product.getProPic());
                return productVO;
            }).collect(Collectors.toList());
        }

        //3.装填分页数据
        PageInfo<ProductHotVO> pageInfo = new PageInfo<>(hotProductVOList);
        pageInfo.setTotal(p.getTotal());
        pageInfo.setPages(p.getPages());
        return JsonPage.restPage(pageInfo);
    }

    /**
     * 根据分类id查询商品列表数据
     */
    @Override
    public List<ProductVO> listProductByCategoryId(Integer categoryId) {
        List<Product> productList = productMapper.listProductByCategoryId(categoryId);

        //2.装填VO内容
        List<ProductVO> productVOList = new ArrayList<>();
        if (Objects.nonNull(productList) && !productList.isEmpty()) {
            productVOList = productList.stream().map(product -> {
                ProductVO productVO = new ProductVO();
                BeanUtils.copyProperties(product, productVO);
                productVO.setProPic(imageProperties.getUrl() + product.getProPic());
                return productVO;
            }).collect(Collectors.toList());
        }

        return productVOList;
    }

    /**
     * 根据商品id查询商品详情
     */
    @Override
    public ProductDetailVO getProductDetail(Integer productId) {
        ProductDetailVO productDetailVO = new ProductDetailVO();

        //1.异步查询商品信息
        CompletableFuture<Void> productInfo = CompletableFuture.runAsync(() -> {
            Product product = productMapper.getProductById(productId);
            product.setProPic(imageProperties.getUrl() + product.getProPic());
            BeanUtils.copyProperties(product, productDetailVO);
        }, executor);

        //2.异步查询商品轮播图信息
        CompletableFuture<Void> productSwiper = CompletableFuture.runAsync(() -> {
            List<ProductSwiperImage> productSwiperImages = productSwiperImageMapper.listSwiperImageByProductId(productId);
            List<String> imageUrlList = productSwiperImages.stream()
                    .map(swiperImage -> imageProperties.getUrl() + swiperImage.getImage()).collect(Collectors.toList());
            productDetailVO.setSwiperImgs(imageUrlList);
        }, executor);

        //3.等待异步返回结果
        try {
            CompletableFuture.allOf(productInfo, productSwiper).get();
        } catch (Exception e) {
            throw new BusinessException(StatusCode.FAILED);
        }

        return productDetailVO;
    }

    /**
     * 扣减库存
     * @param productId 商品id
     * @param num       数量
     */
    @Override
    public void reduceStock(Integer productId, Integer num) {
        productMapper.reduceStock(productId, num);
    }

    @Override
    public JsonPage<ProductVO> searchProduct(SearchParam searchParam) {
        //分页模糊查询商品
        Page<Object> p = PageHelper.startPage(searchParam.getPage(), searchParam.getPageSize());
        List<Product> productList = productMapper.listByCondition(searchParam);

        //装填VO内容
        List<ProductVO> productVOList = productList.stream().map(product -> {
            ProductVO productVO = new ProductVO();
            BeanUtils.copyProperties(product, productVO);
            productVO.setProPic(imageProperties.getUrl() + product.getProPic());
            return productVO;
        }).collect(Collectors.toList());

        PageInfo<ProductVO> pageInfo = new PageInfo<>(productVOList);
        pageInfo.setTotal(p.getTotal());
        pageInfo.setPages(p.getPages());
        pageInfo.setPageNum(p.getPageNum());
        pageInfo.setPageSize(p.getPageSize());
        return JsonPage.restPage(pageInfo);
    }
}
